package com.stox.client.ui.javafx.chartingy.model.shape;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.Label;
import javafx.scene.shape.Line;

import com.stox.client.ui.javafx.chartingy.model.chart.Chart;
import com.stox.shared.util.Constant;

public class HorizontalLine extends Shape {

	private final ControlPoint controlPoint;
	private final Line line = new Line();
	private final Label valueLabel = new Label();
	private final ChangeListener<Number> changeListener = new ChangeListener<Number>() {
		@Override
		public void changed(final ObservableValue<? extends Number> observable, final Number oldValue, final Number newValue) {
			controlPoint.setCenterX((line.getStartX() + line.getEndX()) / 2);
		}
	};

	public HorizontalLine(final Chart<?, ?> chart, final double initialSceneY) {
		super(chart);
		controlPoint = new ControlPoint(chart) {
			@Override
			protected void dragToX(final double sceneX) {
				// No Op - User should not be able to drag it horizontally
			}

			@Override
			public void update() {
				super.update();
				setCenterX((chart.getChartContentArea().getLayoutX() + chart.getChartContentArea().getWidth()) / 2);
			}
		};

		line.startYProperty().bindBidirectional(line.endYProperty());
		line.startXProperty().bind(chart.getChartContentArea().layoutXProperty().add(deletePoint.radiusProperty().multiply(2)));
		deletePoint.centerXProperty().bind(line.startXProperty().subtract(deletePoint.radiusProperty()));
		deletePoint.centerYProperty().bind(line.startYProperty());
		line.endXProperty().bind(chart.getChartContentArea().layoutXProperty().add(chart.getChartContentArea().widthProperty()));
		line.startYProperty().bindBidirectional(controlPoint.centerYProperty());
		line.startXProperty().addListener(changeListener);
		line.endXProperty().addListener(changeListener);

		valueLabel.layoutXProperty().bind(chart.getValueAxis().layoutXProperty());
		valueLabel.layoutYProperty().bind(controlPoint.centerYProperty().subtract(valueLabel.heightProperty().divide(2)));
		controlPoint.centerYProperty().addListener(new ChangeListener<Number>() {
			@Override
			public void changed(final ObservableValue<? extends Number> observable, final Number oldValue, final Number newValue) {
				valueLabel.setText(Constant.numberFormat.format(chart.getValueAxis().getValueForDisplay(newValue.doubleValue())));
			}
		});

		final double mid = (chart.getChartContentArea().getLayoutX() + chart.getChartContentArea().getWidth()) / 2;
		controlPoint.setCenterX(mid);
		controlPoint.setCenterY(chart.getChartContentArea().sceneToLocal(mid, initialSceneY).getY());

		getChildren().addAll(deletePoint, line, controlPoint, valueLabel);
	}


	@Override
	public void update() {
		controlPoint.update();
	}

	public ControlPoint getControlPoint() {
		return controlPoint;
	}

	public Line getLine() {
		return line;
	}
}
